package fr.umlv.m2.jee.spij.persistence.education;

import fr.umlv.m2.jee.spij.persistence.actor.TeacherUnit;
import fr.umlv.m2.jee.spij.persistence.schooling.Course;
import fr.umlv.m2.jee.spij.persistence.schooling.Registration;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Entity Unit who contain information about unit.
 *
 * @author Lounes Akroune
 * @author Aurelien Scelles
 */
@Entity
@Table(name = "UNI_UNIT")
public class Unit implements Serializable {

    /**
     * Primary key.
     */
    @Id
    @Column(name = "UNI_ID", nullable = false, unique = true, updatable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    /**
     * Name of unit.
     */
    @Column(name = "UNI_NAME", nullable = false, unique = true)
    private String name;

    /**
     *
     */
    @Column(name = "UNI_CREDIT", nullable = false)
    private int credit;

    /**
     * List of teachers
     */
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "TL_UNI_ID", referencedColumnName = "UNI_ID")
    private List<TeacherUnit> teachers = new ArrayList<TeacherUnit>();

    /**
     * List of quiz
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "QUI_UNI_ID", referencedColumnName = "UNI_ID")
    private List<Quiz> quiz = new ArrayList<Quiz>();

    /**
     * List of Lessons
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "LES_UNI_ID", referencedColumnName = "UNI_ID")
    private List<Lesson> lessons = new ArrayList<Lesson>();

    /**
     * List of tutorials
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "TUT_UNI_ID", referencedColumnName = "UNI_ID")
    private List<Tutorial> tutorials = new ArrayList<Tutorial>();

    /**
     * List of field works
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "FIE_UNI_ID", referencedColumnName = "UNI_ID")
    private List<FieldWork> fieldWorks = new ArrayList<FieldWork>();

    /**
     * List of parials
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "PAR_UNI_ID", referencedColumnName = "UNI_ID")
    private List<Partial> partials = new ArrayList<Partial>();

    /**
     * List of Projects
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "PRO_UNI_ID", referencedColumnName = "UNI_ID")
    private List<Project> projects = new ArrayList<Project>();

    /**
     * List of Remedials
     */
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "REM_UNI_ID", referencedColumnName = "UNI_ID")
    private List<Remedial> remedials = new ArrayList<Remedial>();

    /**
     * Link between units and keywords
     */
    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name = "UNI_AND_KEY", joinColumns = {@JoinColumn(name = "UNI_ID", referencedColumnName = "UNI_ID")}, inverseJoinColumns = {@JoinColumn(name = "KEY_ID", referencedColumnName = "KEY_ID")})
    private List<KeyWord> keyWords = new ArrayList<KeyWord>();

    /**
     * Link between units and registrations.
     */
    @ManyToMany(cascade = {CascadeType.ALL}, mappedBy = "units")
    private List<Registration> registrations = new ArrayList<Registration>();

    /**
     * Link between units and registrations.
     */
    @ManyToMany(cascade = {CascadeType.ALL}, mappedBy = "requiredUnits")
    private List<Course> requiredCourse = new ArrayList<Course>();

    /**
     * Link between units and registrations.
     */
    @ManyToMany(cascade = {CascadeType.ALL}, mappedBy = "optionalUnits")
    private List<Course> optionalCourse = new ArrayList<Course>();

    /**
     * Setter of id.
     *
     * @param id
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * Getter of id.
     *
     * @return primary key
     */
    public long getId() {
        return id;
    }

    /**
     * Setter of name.
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Getter of name.
     *
     * @return name of Unit.
     */
    public String getName() {
        return name;
    }

    /**
     * Setter of credit.
     *
     * @param credit
     */
    public void setCredit(int credit) {
        this.credit = credit;
    }

    /**
     * Getter of credit.
     *
     * @return credit of unit
     */
    public int getCredit() {
        return credit;
    }

    public List<TeacherUnit> getTeachers() {
        return teachers;
    }

    public void setTeachers(List<TeacherUnit> teachers) {
        this.teachers = teachers;
    }

    /**
     * Setter of quiz.
     *
     * @param quiz
     */
    public void setQuiz(List<Quiz> quiz) {
        this.quiz = quiz;
    }

    /**
     * Getter of quiz.
     *
     * @return list of quiz
     */
    public List<Quiz> getQuiz() {
        return quiz;
    }

    /**
     * Setter of lessons.
     *
     * @param lessons
     */
    public void setLessons(List<Lesson> lessons) {
        this.lessons = lessons;
    }

    /**
     * Getter of lessons.
     *
     * @return list of lessons
     */
    public List<Lesson> getLessons() {
        return lessons;
    }

    /**
     * Setter of tutorials.
     *
     * @param tutorials
     */
    public void setTutorials(List<Tutorial> tutorials) {
        this.tutorials = tutorials;
    }

    /**
     * Getter of tutorials.
     *
     * @return list of tutorials.
     */
    public List<Tutorial> getTutorials() {
        return tutorials;
    }

    /**
     * Setter of fieldWorks.
     *
     * @param fieldWorks
     */
    public void setFieldWorks(List<FieldWork> fieldWorks) {
        this.fieldWorks = fieldWorks;
    }

    /**
     * Getter of fieldWorks.
     *
     * @return list of fieldWorks
     */
    public List<FieldWork> getFieldWorks() {
        return fieldWorks;
    }

    /**
     * Setter of partials.
     *
     * @param partials
     */
    public void setPartials(List<Partial> partials) {
        this.partials = partials;
    }

    /**
     * Getter of partials.
     *
     * @return list of partials
     */
    public List<Partial> getPartials() {
        return partials;
    }

    /**
     * Setter of projects.
     *
     * @param projects
     */
    public void setProjects(List<Project> projects) {
        this.projects = projects;
    }

    /**
     * Getter of projects.
     *
     * @return list of project
     */
    public List<Project> getProjects() {
        return projects;
    }

    /**
     * Setter of remedials.
     *
     * @param remedials
     */
    public void setRemedials(List<Remedial> remedials) {
        this.remedials = remedials;
    }

    /**
     * Getter of remedials.
     *
     * @return list of remedials
     */
    public List<Remedial> getRemedials() {
        return remedials;
    }

    /**
     * Setter of keyWords.
     *
     * @param keyWords
     */
    public void setKeyWords(List<KeyWord> keyWords) {
        this.keyWords = keyWords;
    }

    /**
     * Getter of keyWords.
     *
     * @return list of keywords
     */
    public List<KeyWord> getKeyWords() {
        return keyWords;
    }

    /**
     * Setter of registrations.
     *
     * @param registrations
     */
    public void setRegistrations(List<Registration> registrations) {
        this.registrations = registrations;
    }

    /**
     * Getter of registrations.
     *
     * @return list of registrations
     */
    public List<Registration> getRegistrations() {
        return registrations;
    }

}
